package Util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.util.TypeUtils;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.math.BigDecimal;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 字符串工具类
 */
public class StringUtils {

    //region isEmpty 检验字符串是否为空：null和空字符串

    /**
     * 检验字符串是否为空：null和空字符串
     *
     * @param obj 数据
     * @return boolean
     */
    public static boolean isEmpty(Object obj) {
        return obj == null || "".equals(obj.toString().trim());
    }
    //endregion

    //region 字符串转换

    /**
     * 转换成字符串
     *
     * @param obj 数据对象
     * @return String
     */
    public static String toString(Object obj) {
        if (obj == null) {
            return "";
        }
        return obj.toString();
    }

    /**
     * null转空字符串
     *
     * @param obj 数据对象
     * @return String
     */
    public static String notNull(String obj) {
        if (obj == null) {
            return "";
        }
        return obj;
    }

    /**
     * 转换成int
     *
     * @param obj 数据对象
     * @return int
     */
    public static int toInt(Object obj) {
        String objStr = toString(obj);
        if (isEmpty(objStr)) {
            return 0;
        }
        int result = 0;
        try {
            result = Integer.parseInt(objStr);
        } catch (Exception e) {
        }
        return result;
    }

    /**
     * 转换成byte
     *
     * @param byteStr 数据对象
     * @return int
     */
    public static byte toByte(String byteStr) {
        if (isEmpty(byteStr)) {
            return 0;
        }
        byte result = 0;
        try {
            result = Byte.parseByte(byteStr);
        } catch (Exception e) {
        }
        return result;
    }

    /**
     * 转换成double
     *
     * @param obj 数据对象
     * @return double
     */
    public static BigDecimal toBigDecimal(Object obj) {
        String objStr = toString(obj);
        BigDecimal result = BigDecimal.ZERO;
        if (isEmpty(objStr)) {
            return result;
        }
        try {
            result = new BigDecimal(objStr);
        } catch (Exception e) {
        }
        return result;
    }

    /**
     * 转换成long
     *
     * @param obj 数据对象
     * @return long
     */
    public static long toLong(Object obj) {
        String objStr = toString(obj);
        if (isEmpty(objStr)) {
            return 0;
        }
        long result = 0;
        try {
            result = Long.parseLong(objStr);
        } catch (Exception e) {
        }
        return result;
    }

    /**
     * 转换成boolean
     *
     * @param obj 数据对象
     * @return long
     */
    public static boolean toBoolean(Object obj) {
        String objStr = toString(obj);
        if (isEmpty(objStr)) {
            return false;
        }
        boolean result = false;
        try {
            result = Boolean.parseBoolean(objStr);
        } catch (Exception e) {
            return false;
        }
        return result;
    }

    /**
     * 转换成时间
     *
     * @param dateStr 时间字符串
     * @return Date
     */
    public static Date toDate(String dateStr) {
        Date newDate = null;
        try {
            newDate = TypeUtils.castToDate(dateStr);
        } catch (Exception e) {

        }
        return newDate;
    }

    //region format 占位符拼接字符串

    /**
     * 占位符拼接字符串
     *
     * @param format 要格式化的完整字符串
     * @param objs   数据
     * @return
     */
    public static String format(String format, Object... objs) {
        StringBuilder sb = new StringBuilder();
        if (isEmpty(format)) {
            return "";
        }
        if (format.indexOf("{}") < 0) {
            return format;
        }
        String[] formatArr = format.split("\\{}");
        if (formatArr.length < 2) {
            return formatArr[0];
        }
        if (objs != null || objs.length > 0) {
            for (int i = 0; i < formatArr.length; i++) {
                sb.append(formatArr[i] + toString(objs[i]));
            }
        }
        return sb.toString();
    }
    //endregion
    // endregion

    //region 时间相关工具方法

    //region formatDateToString 格式化时间

    /**
     * 格式化时间
     *
     * @param date      时间
     * @param formatStr 格式化的字符串：yyyyMMddHHmmss,yyyyMMdd,HHmmss等
     * @return String
     */
    public static String formatDateToString(Date date, String formatStr) {
        return new SimpleDateFormat(formatStr).format(date);
    }
    //endregion

    //region getTimestamp  获取时间戳

    /**
     * 获取时间戳
     *
     * @return long
     */
    public static long getTimestamp() {
        return System.currentTimeMillis() / 1000;
    }
    //endregion

    //region compare 时间比较

    /**
     * 时间比较
     *
     * @param time1        时间1
     * @param time2        时间2
     * @param formatString 时间格式字符串
     * @return true/false
     * @throws ParseException
     */
    public static boolean dateCompare(String time1, String time2, String formatString) {
        SimpleDateFormat sdf = new SimpleDateFormat(formatString);
        Date a = null;
        try {
            a = sdf.parse(time1);
        } catch (ParseException e) {
            e.printStackTrace();
            return false;
        }
        Date b = null;
        try {
            b = sdf.parse(time2);
        } catch (ParseException e) {
            return false;
        }
        //如果a早于b返回true，否则返回false
        return a.before(b);
    }
    //endregion

    //endregion

    //region 参数A-Z排序

    /**
     * 参数A-Z排序
     *
     * @param jsonData json 数据
     * @return String
     */
    public static String jsonDataSortAToZ(JSONObject jsonData) {
        Map<String, Object> map = jsonData.getInnerMap();
        List<Map.Entry<String, Object>> list = new ArrayList<>(map.entrySet());
        //升序排序
        list.sort(Comparator.comparing(Map.Entry::getKey));
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, Object> mapping : list) {
            if (mapping.getValue() == null || "".equals(mapping.getValue())) {
                continue;
            }
            if (sb.length() > 0) {
                sb.append("&");
            }
            sb.append(mapping.getKey());
            sb.append("=");
            sb.append(mapping.getValue());
        }
        return sb.toString();
    }

    /**
     * 参数A-Z排序
     *
     * @param mapData map 数据
     * @return String
     */
    public static String mapDataSortAToZ(Map<String, Object> mapData) {
        List<Map.Entry<String, Object>> list = new ArrayList<>(mapData.entrySet());
        //升序排序
        list.sort(Comparator.comparing(Map.Entry::getKey));
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, Object> mapping : list) {
            if (mapping.getValue() == null || "".equals(mapping.getValue())) {
                continue;
            }
            if (sb.length() > 0) {
                sb.append("&");
            }
            sb.append(mapping.getKey());
            sb.append("=");
            sb.append(mapping.getValue());

        }
        return sb.toString();
    }
    //endregion

    //region formatPrettyObject 格式化输出

    /**
     * 格式化输出
     *
     * @param object 格式化对象
     * @return String
     */
    public static String formatPrettyObject(Object object) {
        String result = "";
        if (object == null || "".equals(object)) {
            return result;
        }
        if (object.getClass() == String.class) {
            result = JSONObject.toJSONString(JSONObject.parseObject(object.toString()), SerializerFeature.PrettyFormat);
        } else {
            result = JSONObject.toJSONString(object, SerializerFeature.PrettyFormat);
        }
        return result;
    }
    //endregion

    //region bytesToHexString bytes[]换成16进制字符串

    /**
     * bytes[]换成16进制字符串
     *
     * @param bytes byte数组
     * @return String
     */
    public static String bytesToHexString(byte[] bytes) {
        StringBuilder stringBuilder = new StringBuilder();
        if (bytes == null || bytes.length <= 0) {
            return null;
        }
        for (byte aByte : bytes) {
            int v = aByte & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString().toUpperCase();
    }
    //endregion

    //region hexStringToBytes 16进制转byte数组

    /**
     * Hex字符串转byte
     *
     * @param inHex 待转换的Hex字符串
     * @return 转换后的byte
     */
    public static byte hexToByte(String inHex) {
        return (byte) Integer.parseInt(inHex, 16);
    }

    /**
     * hex字符串转byte数组
     *
     * @param inHex 待转换的Hex字符串
     * @return 转换后的byte数组结果
     */
    public static byte[] hexStringToBytes(String inHex) {
        int hexlen = inHex.length();
        byte[] result;
        if (hexlen % 2 == 1) {
            //奇数
            hexlen++;
            result = new byte[(hexlen / 2)];
            inHex = "0" + inHex;
        } else {
            //偶数
            result = new byte[(hexlen / 2)];
        }
        int j = 0;
        for (int i = 0; i < hexlen; i += 2) {
            result[j] = hexToByte(inHex.substring(i, i + 2));
            j++;
        }
        return result;
    }
    //endregion

    //region bytesToBase64 bytes[]转换成Base64字符串

    /**
     * bytes[]转换成Base64字符串
     *
     * @param bytes byte数组
     * @return String
     */
    public static String bytesToBase64(byte[] bytes) {
        if (bytes == null || bytes.length <= 0) {
            return "";
        }
        return Base64.getEncoder().encodeToString(bytes);
    }

    /**
     * 字符串转换成Base64字符串
     *
     * @param data    数据
     * @param charset 字符集
     * @return String
     */
    public static String bytesToBase64(String data, String charset) {
        if (isEmpty(data)) {
            return "";
        }
        if (isEmpty(charset)) {
            charset = "utf-8";
        }
        try {
            byte[] bytes = data.getBytes(charset);
            return Base64.getEncoder().encodeToString(bytes);
        } catch (Exception ex) {
            return data;
        }
    }
    //endregion

    //region base64ToBytes Base64字符串转byte数组

    /**
     * Base64字符串转byte数组
     *
     * @param base64Str
     * @return
     */
    public static byte[] base64ToBytes(String base64Str) {
        if (isEmpty(base64Str)) {
            return null;
        }
        try {
            return Base64.getDecoder().decode(base64Str);
        } catch (Exception ex) {
            return null;
        }
    }
    //endregion


    //region getNonceStr 获取随机字符串 32位

    /**
     * 获取随机字符串 32位
     *
     * @return String
     */
    public static String getNonceStr() {
        return UUID.randomUUID().toString().replace("-", "").toUpperCase();
    }
    //endregion

    // region 删除json字符串中value的首尾空白字符

    /**
     * 删除json字符串中value的首尾空白字符
     *
     * @param jsonString 返回处理后的json字符串
     */
    public static String trimJsonStringWhitespace(String jsonString) {
        if (StringUtils.isEmpty(jsonString)) {
            return null;
        }
        try {
            String bizContent = jsonString;
            JSONObject params = JSONObject.parseObject(bizContent);
            for (String key : params.keySet()) {
                Object value = params.get(key);
                if (value instanceof String) {
                    value = org.springframework.util.StringUtils.trimLeadingWhitespace(value.toString());
                    value = org.springframework.util.StringUtils.trimTrailingWhitespace(value.toString());
                    params.put(key, value);
                }
            }
            return JSON.toJSONString(params);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    //endregion

    //region urlEncode/urlDecode

    /**
     * url编码，默认utf-8
     *
     * @param encodeStr 要编码的数据
     * @return String
     */
    public static String urlEncode(String encodeStr) {
        return urlEncode(encodeStr, "utf-8");
    }

    /**
     * url编码
     *
     * @param encodeStr 要编码的数据
     * @param charset   字符集编码
     * @return String
     */
    public static String urlEncode(String encodeStr, String charset) {
        if (isEmpty(encodeStr)) {
            return "";
        }
        try {
            encodeStr = URLEncoder.encode(encodeStr, charset);
        } catch (Exception ex) {
        }
        return encodeStr;
    }

    /**
     * url解码，默认utf-8
     *
     * @param decodeStr 要解码的数据
     * @return String
     */
    public static String urlDecode(String decodeStr) {
        return urlDecode(decodeStr, "utf-8");
    }

    /**
     * url解码
     *
     * @param decodeStr 要解码的数据
     * @param charset   字符集编码
     * @return String
     */
    public static String urlDecode(String decodeStr, String charset) {
        if (isEmpty(decodeStr)) {
            return "";
        }
        try {
            decodeStr = URLDecoder.decode(decodeStr, charset);
        } catch (Exception ex) {
        }
        return decodeStr;
    }
    //endregion

    //region fenToYuan/yuanTofen 金额分~元转换

    /**
     * 分转元。分必须是正整数
     *
     * @param fen
     * @return
     */
    public static String fenToYuan(Integer fen) {
        if (fen <= 0) return null;

        if (fen >= 100) {
            String sfen = fen.toString();
            Integer len = sfen.length();
            String yuan = sfen.substring(0, len - 2);
            return yuan + "." + sfen.substring(len - 2, len);
        }
        if (fen >= 10 && fen < 100) {
            return "0." + fen.toString();
        }
        if (fen < 10) return "0.0" + fen.toString();
        return null;
    }

    /**
     * 元转分
     *
     * @param yuan
     * @return Integer
     */
    public static Integer yuanTofen(String yuan) {
        if (isEmpty(yuan)) return 0;
        String pattern = "^?[0-9]+?(.?[0-9]{0,4})";

        if (yuan.matches(pattern)) {
            String[] ss = yuan.split("\\.");
            if (ss.length == 1) {
                return Integer.valueOf(ss[0] + "00");
            } else if (ss.length == 2) {
                if (ss[1].length() >= 2) {//如果3,4位小数，直接忽略。
                    return Integer.valueOf(ss[0] + ss[1].substring(0, 2));
                } else if (ss[1].length() == 1) {
                    return Integer.valueOf(ss[0] + ss[1] + "0");
                } else {
                    return Integer.valueOf(ss[0] + "00");
                }
            } else {
                return 0;
            }
        } else {
            return 0;
        }
    }
    //endregion

    //region parseDataToMap 将响应数据为xxx=xxx&xx=xx&x=x或者xxx=xxx|xx=xx|x=x数据转换为Map

    /**
     * 将响应数据为xxx=xxx&xx=xx&x=x或者xxx=xxx|xx=xx|x=x数据转换为Map
     *
     * @param data 数据
     * @return Map<String, String>
     */
    public static Map<String, String> parseDataToMap(String data, String splitString) {
        Map<String, String> mapData = new HashMap<>();
        if (StringUtils.isEmpty(data)) {
            return mapData;
        }
        String[] arr = data.split(splitString);
        for (String d : arr) {
            String[] newArr = d.split("=");
            if (newArr.length > 1) {
                mapData.put(newArr[0], newArr[1]);
            } else {
                mapData.put(newArr[0], "");
            }
        }
        return mapData;
    }
    //endregion

    public static JsonNode parseJsonResponse(String jsonResponse) throws Exception {
        ObjectMapper objectMapper = new ObjectMapper();
        return objectMapper.readTree(jsonResponse);
    }
}
